<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    // Javascript的对象(Object) 本质上是键值对的集合(Hash结构) 传统只能用字符串当作键 给使用带来很大麻烦
    // 为了解决这个问题 ES6提供了Map数据结构 类似于对象 也是键值对的集合 但是键的范围不限于字符串 各种类型的值包括对象都可以作为键
    // Object结构提供 ‘ 字符串 <===> 值 ’ 的对应
    // Map结构提供 ‘ 值 <===> 值 ’ 的对应


    // 把o当作m的一个键
    const m = new Map();
    const o = {p: 'Hello World'};

    m.set(o, 'content')
    m.get(o) // "content"

    m.has(o) // true
    m.delete(o) // true
    m.has(o) // false

    
    // Map接受一个数组作为参数
    // 成员是一个个表示键值对的数组

    const map1 = new Map([
        ['name', '张三'],
        ['title', 'Author']
    ]);

    map1.size // 2
    map1.has('name') // true
    map1.get('name') // "张三"
    map1.has('title') // true
    map1.get('title') // "Author"


    // Map构造函数接受数组作为参数 实际上执行的是下面的算法
    const items = [
        ['name', '张三'],
        ['title', 'Author']
    ];

    const map2 = new Map();

    items.forEach(
        ([key, value]) => map2.set(key, value)
    );


    // 事实上 不仅仅是数组 任何具有Iterator接口、且每个成员都是一个双元素的数组的数据结构都可以当作Map构造函数的参数
    // Set和Map都可以用来生成新的Map
    // 举一个例子
    const set = new Set([
        ['foo', 1],
        ['bar', 2]
    ]);
    const m1 = new Map(set);
    console.log(set) // Set(2) {Array(2), Array(2)}
    console.log(m1) // Map(2) {"foo" => 1, "bar" => 2}
    m1.get('foo') // 1

    const m2 = new Map([['baz', 3]]);
    const m3 = new Map(m2);
    console.log(m2) // Map(1) {"baz" => 3}
    console.log(m3) // Map(1) {"baz" => 3}
    m3.get('baz') // 3

    
    // 如果对同一个键多次赋值 后面的值将覆盖前面的值
    const map3 = new Map();

    map3
    .set(1, 'aaa')
    .set(1, 'bbb');

    map3.get(1) // "bbb"


    // 如果读取一个未知的键 则返回undefined
    new Map().get('asfddfsasadf')
    // undefined


    // 注意 只有对同一个对象的引用 Map结构才将其视为同一个键 要非常小心
    const map4 = new Map();
    map4.set(['a'], 555);
    map4.get(['a']); // undefined
    // 上面代码的set和get方法
    // 表面是针对同一个键 但实际上这是两个值 内存地址是不一样的 因此get方法无法读取该键 返回undefined。


</script>